package com.channel.connector.ctripos.common.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.channel.connector.ctripos.config.OrderCallConfig;
import com.channel.connector.ctripos.dto.ResponseDTO;
import com.channel.connector.ctripos.dto.bms.response.SupplyProductPriceResponseDTO;
import com.channel.connector.ctripos.enums.ErrorCodeEnum;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.util.Collection;

/**
 *
 */
@Slf4j
public class OrderInterfaceInvoker {

    public static ResponseDTO preBooking(OrderCallConfig orderCallConfig, String requestJson) {
        ResponseDTO<Collection<SupplyProductPriceResponseDTO>> responseDTO = new ResponseDTO<>();

        String preBookingUrl = orderCallConfig.getPreBookingUrl();
        ResponseDTO<String> remoteResponse = invoke(requestJson, preBookingUrl);

        //这种属于还未进行远程调用，或者远程调用异常了没正常返回的。
        if (!returnSuccess(remoteResponse)) {
            log.error("试预定异常：{}", requestJson);
            copyResponseDTO(remoteResponse, responseDTO);
            return responseDTO;
        }

        //正常返回之后，model里面存储的是返回的JSON串
        responseDTO = JSON.parseObject(remoteResponse.getModel(), new TypeReference<ResponseDTO<Collection<SupplyProductPriceResponseDTO>>>() {
        });

        return responseDTO;
    }

    public static ResponseDTO<Integer> addManualOrder(OrderCallConfig orderCallConfig, String requestJson) {
        ResponseDTO<Integer> responseDTO = new ResponseDTO();
        String createOrderUrl = orderCallConfig.getCreateUrl();
        ResponseDTO<String> remoteResponse = invoke(requestJson, createOrderUrl);
        //这种属于还未进行远程调用，或者远程调用异常了没正常返回的。
        if (!returnSuccess(remoteResponse)) {
            log.error("下单异常：{}", requestJson);
            copyResponseDTO(remoteResponse, responseDTO);
            return responseDTO;
        }

        responseDTO = JSON.parseObject(remoteResponse.getModel(), ResponseDTO.class);

        return responseDTO;
    }

    public static ResponseDTO addOrderRequest(OrderCallConfig orderCallConfig, String requestJson) {
        ResponseDTO<Integer> responseDTO = new ResponseDTO();
        String addOrderRequestUrl = orderCallConfig.getAddOrderRequestUrl();
        ResponseDTO<String> remoteResponse = invoke(requestJson, addOrderRequestUrl);
        if (!returnSuccess(remoteResponse)) {
            log.error("取消订单插入取消申请信息异常：{}", requestJson);
            copyResponseDTO(remoteResponse, responseDTO);
            return responseDTO;
        }

        responseDTO = JSON.parseObject(remoteResponse.getModel(), ResponseDTO.class);

        return responseDTO;
    }


    private static ResponseDTO<String> invoke(String requestJson, String url) {

        log.info("调用BMS，请求地址:{};请求参数:{};", url, requestJson);

        if (!StringUtil.isValidString(url)) {
            log.error("请求的URL为空:{}", requestJson);
            return new ResponseDTO(ErrorCodeEnum.BMS_ORDER_URL_INVALID);
        }

        String responseStr = null;
        try {
            responseStr = HttpClientUtil.postJson(url, requestJson);
        } catch (IOException e) {
            log.error("请求BMS时IO异常,地址：{}，参数：{}", requestJson, url, e);
            return new ResponseDTO(ErrorCodeEnum.IO_EXCEPTION);
        }

        ResponseDTO<String> responseDTO = new ResponseDTO<>(ErrorCodeEnum.SUCCESS);
        responseDTO.setModel(responseStr);

        log.info("请求地址:{};请求参数:{};返回参数：{}", url, requestJson, JSON.toJSON(responseDTO));
        return responseDTO;
    }


    /**
     * @param responseDTO
     * @return true:表示成功，false：表示失败
     */
    private static boolean returnSuccess(ResponseDTO responseDTO) {
        return 1 == responseDTO.getResult();
    }

    private static void copyResponseDTO(ResponseDTO<String> sourceResponse, ResponseDTO targetResponse) {
        targetResponse.setFailCode(sourceResponse.getFailCode());
        targetResponse.setFailReason(sourceResponse.getFailReason());
        targetResponse.setResult(sourceResponse.getResult());
    }
}
